package com.chiangleoi.appointment.appointments;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.chiangleoi.appointment.model.SiteInfo;
import com.chiangleoi.appointment.model.SiteJsonInfo;
import com.chiangleoi.appointment.model.UserJson;
import com.chiangleoi.appointment.model.vo.SubscribeUserRequest;
import com.chiangleoi.appointment.utils.BeanCopyUtil;
import com.chiangleoi.appointment.utils.SubscribeUtils;
import com.chiangleoi.appointment.utils.SvCipherUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class GuDingBadmintonTrainKillFor {

    static final String url = "https://jntyzx.cn:8443/GYM-JN/multi/Subscribe/addSubscribe";//指定URL

    private static boolean isRunning = true;
    //    private static boolean isCall = true;
    private static boolean isCall = true;
    private static boolean isMock = false;

    public static void main(String[] args) throws Exception {
        printDebug();

        System.out.println("---------------------- 准备获取预订的场地 -------------------------");
        Date today = new Date();
        DateTime dateTime = DateUtil.offsetDay(today, 1);
        boolean isWeekend = DateUtil.isWeekend(dateTime);

        List<SiteJsonInfo> siteJsonInfoList = randomSite(isWeekend);
        SiteJsonInfo siteJsonInfo = siteJsonInfoList.get(0);

        String appointments = siteJsonInfo.getAppointments();
        System.out.println(appointments + "是否为周末:" + isWeekend);

        ObjectMapper objectMapper = new ObjectMapper();
        String siteJsonInfoListJSON = objectMapper.writeValueAsString(siteJsonInfoList);
        System.out.println("当前预约场地列表JSON:" + siteJsonInfoListJSON);

        List<UserJson> userList = getUserList();
        List<UserJson> killUserList = getKillUserList();
        String svCiphertext = SvCipherUtils.getSvCiphertext(siteJsonInfoListJSON);

        System.out.println("---------------------- 组装请求JSON串 -------------------------");

        List<String> postRequestJsonList = new ArrayList<>();

        // 抢跑列表
        System.out.println("---------------------- 抢跑列表 -------------------------");
        for (UserJson userJson : userList) {
            System.out.println("抢跑者:" + userJson.getNickName());
            String userPostJson = getUserPostJson(userJson, siteJsonInfo.getAppointments(), siteJsonInfo, svCiphertext);
            postRequestJsonList.add(userPostJson);
        }

        // 杀牛列表
        List<String> postKillRequestJsonList = new ArrayList<>();
        System.out.println("---------------------- 杀牛列表 -------------------------");
        for (UserJson userJson : killUserList) {
            System.out.println("被杀的牛:" + userJson.getNickName());
            String userPostJson = getUserPostJson(userJson, siteJsonInfo.getAppointments(), siteJsonInfo, svCiphertext);
            postKillRequestJsonList.add(userPostJson);
        }

        printDebug();
        System.out.println("---------------------- 请求JSON组装完毕 -------------------------");
        System.out.println("---------------------- 准备定时请求至接口 -------------------------");


        call(postRequestJsonList, postKillRequestJsonList);
    }

    private static List<UserJson> getKillUserList() {
        List<UserJson> userJsons = new ArrayList<>();
        if (isMock) {
            userJsons.add(new UserJson("1876433582606581762", "o21MO1WfE7tccPbef6Odc", "杀杀杀"));
        } else {
            // 阿勇
            //烂
            userJsons.add(new UserJson("1874984022122233858", "o21MX46zGCD1Moj3KTyL0X35vRRA", "任慧"));
        }
        return userJsons;
    }


    private static List<UserJson> getUserList() {
        List<UserJson> userJsons = new ArrayList<>();
        if (isMock) {
            userJsons.add(new UserJson("1876433582606581762", "o21MO1WfE7tccPbef6Odc", "李宪宪"));
        }
        return userJsons;
    }

    public static String getUserPostJson(UserJson userJson, String appointments,
                                         SiteJsonInfo siteJsonInfo, String svCiphertext) {
        SubscribeUserRequest request = new SubscribeUserRequest();
        request.setBookTime(appointments);

        List<SiteJsonInfo> subscribeVos = new ArrayList<>();
        subscribeVos.add(siteJsonInfo);
        request.setSubscribeVos(subscribeVos);

        request.setPaymentMethod("1");
        request.setSvCiphertext(svCiphertext);
        request.setJsonObject(userJson);

        String requestJson = JSON.toJSONString(request);
        System.out.println("当前用户:" + userJson.getNickName() + ", 当前用户的JSON:" + requestJson);
        return requestJson;
    }

    private static List<SiteJsonInfo> randomSite(boolean isWeekend) throws Exception {
        SubscribeUtils subscribeUtils = new SubscribeUtils();
        List<SiteInfo> subscribeList = subscribeUtils.getSubscribeList();

        if (CollectionUtils.isEmpty(subscribeList)) {
            throw new RuntimeException("场地获取失败");
        }

        System.out.println("全部场地:" + JSON.toJSONString(subscribeList));


        List<SiteInfo> subscribeEmptyList = subscribeList.stream()
                .filter(siteInfo -> !"0".equals(siteInfo.getContacts()))
                .filter(siteInfo -> !"培训".equals(siteInfo.getContacts()))
                .filter(siteInfo -> !"系统锁定".equals(siteInfo.getContacts()))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(subscribeEmptyList)) {
            throw new RuntimeException("场地获取失败");
        }

        SiteInfo siteInfo = subscribeEmptyList.get(0);
        System.out.println("从接口获取的siteInfo/JSON:" + JSON.toJSONString(siteInfo));
        SiteJsonInfo siteJsonInfo = BeanCopyUtil.copy(siteInfo, SiteJsonInfo.class);
        siteJsonInfo.setId(0);
        String appointments = siteInfo.getAppointments();
        System.out.println("当前预约时间:" + appointments);
        System.out.println("当前预约场地:" + siteInfo.getPlaceName());
        System.out.println("当前预约时间段:" + siteInfo.getSjName());

        List<SiteJsonInfo> siteJsonInfoList = new ArrayList<>();
        siteJsonInfoList.add(siteJsonInfo);

        return siteJsonInfoList;
    }

    private static void printDebug() {
        if (isCall) {
            System.out.println("【启用】接口调用, isCall:" + isCall);
        } else {
            System.out.println("【不启用】接口调用, isCall:" + isCall);
        }

    }

    private static void call(List<String> postRequestJsonList,
                             List<String> postKillRequestJsonList) throws InterruptedException {
        String callStatus = isCall == true ? "开启" : "未开启";
        String runningStatus = isRunning == true ? "运行" : "未运行";
        String mockStatus = isMock == true ? "Mock" : "非Mock";
        System.out.println("isCall的是否开启:【" + callStatus + "】");
        System.out.println("isRunning的是否运行:【" + runningStatus + "】");
        System.out.println("isMock:【" + mockStatus + "】");

        // 创建自定义的 Dispatcher
        Dispatcher dispatcher = new Dispatcher();
        // 设置最大并发请求数量（可根据需求修改）
        dispatcher.setMaxRequests(100);
        dispatcher.setMaxRequestsPerHost(50);
        // 创建OkHttpClient
        OkHttpClient client = new OkHttpClient().newBuilder().dispatcher(dispatcher).build();
        for (String postData : postKillRequestJsonList) {
            if (isCall) {
                sendKillData(client, postData, 10);
            }
        }

    }


    private static void sendKillData(OkHttpClient client, String postData, int times) {
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(MediaType.parse("application/json"), postData))
                .build();
        for (int i = 0; i <= times; i++) {
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String body = response.body().string();
                    System.out.println("【杀牛】okhttp响应返回:" + body);
                }

                @Override
                public void onFailure(Call call, IOException e) {
                    // 处理失败
                    System.out.println(postData + ":【杀牛】okhttp请求失败: " + e.getMessage());
                }
            });
        }
    }

}
